home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / pcxkit.zip / PCX.ASM < prev    next >
Assembly Source File  |  1992-01-06  |  10KB  |  214 lines

  1. ;============================
  2. ;Linkable module for PCX.PAS
  3. ;============================
  4.  
  5. DATA SEGMENT WORD
  6.  
  7.         extrn   datalength: word
  8.         extrn   scratch: dword
  9.         extrn   abuff0, abuff1: word
  10.         extrn   is_CGA: byte
  11.         extrn   page_addr: word
  12.         extrn   video_index: word
  13.         extrn   columncount: word
  14.         extrn   plane: word
  15.         extrn   repeatcount: byte
  16.         extrn   bytes_per_line: word
  17.  
  18.         writeproc  dw  (?)
  19.  
  20. DATA ENDS
  21.  
  22. CODE SEGMENT WORD PUBLIC
  23.  
  24.         assume cs:code, ds:data
  25.  
  26.         public  decode_pcx
  27.         public  decode_pcx256
  28.  
  29. LOCALS
  30.  
  31. ;==========================================================================
  32.  
  33. ;Here's how the data compression system works. Each byte is either image
  34. ;data or a count byte that tells how often the next image byte is repeated.
  35. ;The byte is image data if it follows a count byte, or if either of the top
  36. ;two bits is clear. Otherwise it is a count byte, with the count derived
  37. ;from the lower 6 bits.
  38.  
  39. GET_DATA_BYTE MACRO
  40.  
  41. @@getbyte:      cmp     si, datalength              ;end of scratch buffer?
  42.                 je      @@exit                      ;yes, quit
  43.                 push    es                          ;save output address
  44.                 push    di
  45.                 les     di, scratch                 ;scratch start in ES:DI
  46.                 add     di, si                      ;add offset
  47.                 mov     al, [es:di]                 ;get byte from scratch
  48.                 inc     si                          ;increment index
  49.                 pop     di                          ;restore output address
  50.                 pop     es
  51.                 cmp     bl, 0                       ;was prev. byte a count?
  52.                 jg      @@repeats                   ;yes, this is data
  53.                 mov     ah, al                      ;no, copy byte to AH
  54.                 and     ah, 192                     ; and test high bits
  55.                 cmp     ah, 192
  56.                 jne     @@is_data                   ;not set, not a count
  57. ;It's a count byte
  58.                 xor     al, 192                     ;get count from 6 low bits
  59.                 mov     bl, al                      ;store repeat count
  60.                 jmp     @@getbyte                   ;go get data byte
  61.  
  62. ENDM
  63.  
  64. ;===================== Store CGA image in buffers ========================
  65.  
  66. STOREBYTE PROC NEAR
  67.  
  68.                 stosb                       ;AL into ES:DI, increment DI
  69.                 inc     dx                  ;increment column count
  70.                 cmp     dx, bytes_per_line
  71.                 je      row_ends            ;end of a row
  72.                 ret                         ;not end of row, so finished
  73. row_ends:       xor     bp, 1               ;switch banks
  74.                 cmp     bp, 1               ;is bank 1?
  75.                 je      bank1               ;yes, jump
  76.                 mov     abuff1, di          ;no, save index into bank 1
  77.                 mov     es, abuff0[2]       ;load bank 0 segment
  78.                 mov     di, abuff0          ;load bank 0 index
  79.                 xor     dx, dx              ;reset column counter
  80.                 ret
  81. bank1:          mov     abuff0, di          ;save index into bank 0
  82.                 mov     es, abuff1[2]       ;load bank 1 segment
  83.                 mov     di, abuff1          ;load bank 1 index
  84.                 xor     dx, dx              ;reset column counter
  85.                 ret
  86.  
  87. STOREBYTE  ENDP
  88.  
  89. ;====================== Write EGA/VGA image to video =====================
  90.  
  91. ;The data in the .PCX file is organized by color plane, by line; that is,
  92. ;all the data for plane 0 for line 1, then for plane 1, line 1, etc.
  93. ;Writing the data to display memory is just a matter of masking out the
  94. ;other planes while one plane is being written to. This is done with the
  95. ;map mask register in the sequencer. All the other weird and wonderful
  96. ;registers in the EGA/VGA do just fine with their default settings, thank
  97. ;goodness.
  98.  
  99. WRITEBYTE PROC NEAR
  100.  
  101.                 stosb                             ;AL into ES:DI, inc DI
  102.                 inc     dx                        ;increment column
  103.                 cmp     dx, bytes_per_line        ;reached end of scanline?
  104.                 je      doneline                  ;yes
  105.                 ret                               ;no, go get a byte
  106. doneline:       shl     bp, 1                     ;shift to next plane
  107.                 cmp     bp, 8                     ;done 4 planes?
  108.                 jle     setindex                  ;no
  109.                 mov     bp, 1                     ;yes, reset plane to 1
  110.                 jmp short setplane                ;  but don't reset index
  111. setindex:       sub     di, dx                    ;reset to start of line
  112. setplane:       push    ax                        ;save data in AL
  113.                 cli                               ;clear interrupts
  114.                 mov     ax, bp                    ;plane is 1, 2, 4, or 8
  115.                 mov     dx, 3C5h                  ;sequencer data register
  116.                 out     dx, al                    ;mask out 3 planes
  117.                 sti                               ;enable interrupts
  118.                 pop     ax                        ;restore data byte
  119.                 xor     dx, dx                    ;reset column count
  120.                 ret
  121.  
  122. WRITEBYTE ENDP
  123.  
  124. ;======================= Decode data from file ===========================
  125.  
  126. DECODE_PCX    PROC    NEAR
  127.  
  128.                 push    bp
  129.                 cmp     is_CGA, 1
  130.                 je      CGAonly
  131.                 mov     bp, plane                   ;store plane in BP
  132.                 mov     es, page_addr               ;video display segment
  133.                 mov     writeproc, offset writebyte ;choose EGA/VGA procedure
  134.                 mov     di, video_index             ;output pointer
  135.                 jmp     short alltypes
  136. CGAonly:        mov     writeproc, offset storebyte ;choose CGA procedure
  137.  
  138. ;It's assumed that CGA files will require only one pass through the buffer,
  139. ;therefore output pointer is initialized to first row bank.
  140.  
  141.                 mov     es, abuff0[2]               ;segment of bank 0 buffer
  142.                 mov     di, abuff0                  ;offset of buffer
  143.                 mov     bp, 0                       ;bank in BP
  144. alltypes:       mov     bl, repeatcount             ;count in BL
  145.                 mov     dx, columncount             ;column counter
  146.                 xor     cx, cx                      ;clean up CH for counter
  147.                 mov     si, cx                      ;initialize scratch ptr.
  148.                 cld                                 ;clear DF for stosb
  149.  
  150. ;--------------------- Loop through scratch buffer ------------------------
  151.  
  152.                 get_data_byte                       ;macro
  153. ;It's a single data byte; call CGA or EGA routine once
  154. @@is_data:      call    writeproc
  155.                 jmp     @@getbyte
  156. ;It's data to be written "count" times; call CGA or EGA routine repeatedly
  157. @@repeats:      mov     cl, bl                      ;set loop counter
  158. @@go:           call    writeproc
  159.                 loop    @@go                        ;write byte CX times
  160.                 mov     bl, 0                       ;clear count byte
  161.                 jmp     @@getbyte
  162.  
  163. ;----------------------- Finished with buffer ----------------------------
  164.  
  165. @@exit:         mov     plane, bp                   ;save status for next
  166.                 mov     repeatcount, bl             ;  run thru buffer
  167.                 mov     columncount, dx
  168.                 mov     video_index, di
  169.                 pop     bp
  170.                 ret
  171.  
  172. DECODE_PCX    ENDP
  173.  
  174. ;==================== Decode data from 256-color file ====================
  175.  
  176. ;The following procedure is fundamentally the same as DECODE_PCX, and the
  177. ;code could be made more compact by merging the two. I've done things this
  178. ;way solely in the interests of speed: it would waste time to call
  179. ;a "writeproc" procedure 64,000 times when that procedure consisted of just
  180. ;a single instruction.
  181.  
  182. DECODE_PCX256    PROC    NEAR
  183.  
  184.                 mov     es, page_addr               ;video segment
  185.                 mov     bl, repeatcount             ;count in BL
  186.                 mov     di, video_index             ;index into video
  187.                 xor     cx, cx                      ;clean up loop counter
  188.                 mov     si, cx                      ;index into scratch
  189.                 cld                                 ;clear DF
  190.  
  191. ;---------------------- Loop through scratch buffer -----------------------
  192.  
  193.                 get_data_byte                       ;macro
  194. ;It's a single data byte
  195. @@is_data:      stosb                               ;byte into video
  196.                 jmp     @@getbyte
  197. ;It's data to be written "count" times
  198. @@repeats:      mov     cl, bl                      ;set counter
  199.                 rep     stosb                       ;write byte CX times
  200.                 mov     bl, 0                       ;clear count byte
  201.                 jmp     @@getbyte
  202.  
  203. ;------------------------- Finished with buffer --------------------------
  204.  
  205. @@exit:         mov     video_index, di             ;save status for next
  206.                 mov     repeatcount, bl             ;  run thru buffer
  207.                 ret
  208.  
  209. DECODE_PCX256   ENDP
  210.  
  211. ;=========================================================================
  212. CODE ENDS
  213. END
  214.